package cn.sharp.bbs.service.impl;

import cn.sharp.bbs.common.Constants;
import cn.sharp.bbs.dao.ReportDao;
import cn.sharp.bbs.dao.gen.CommentMapper;
import cn.sharp.bbs.dao.gen.PostMapper;
import cn.sharp.bbs.dao.gen.ReportMapper;
import cn.sharp.bbs.dao.gen.UserMapper;
import cn.sharp.bbs.entity.BO.CurrentUser;
import cn.sharp.bbs.entity.DO.*;
import cn.sharp.bbs.event.ReportPassEvent;
import cn.sharp.bbs.event.ReportRejectEvent;
import cn.sharp.bbs.service.ReportService;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zhao yu
 */
@Service
public class ReportServiceImpl implements ReportService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private PostMapper postMapper;

    @Resource
    private CommentMapper commentMapper;

    @Resource
    private ReportMapper reportMapper;

    @Resource
    private ReportDao reportDao;

    @Resource
    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public List<ReportReason> getReasonList(int type) {
        return reportDao.getReasonList(type);
    }

    @Override
    public boolean checkID(int type, long id) {
        Object obj =  null;
        switch (type) {
            case 0 :
                obj = postMapper.selectByPrimaryKey(id);
                break;
            case 1 :
                obj = commentMapper.selectByPrimaryKey(id);
                break;
            case 2 :
                obj = userMapper.selectByPrimaryKey(id);
                break;
        }
        return obj != null;
    }

    @Override
    public void report(Report record) {
        reportMapper.insert(record);
        for (ReportReason reason : record.getReportReasonList()) {
            reportDao.insertReason(reason.getReasonId(), reason.getReasonWhy(), record.getId());
        }
    }

    @Override
    public List<ReportDto> getReportList() {
        List<Report> list = reportMapper.selectAll();
        List<ReportDto> reportDtoList = new ArrayList<>();
        for (Report report : list) {
            List<ReportReason> reasonList = reportDao.getReasonList(report.getType());
            for(ReportReason reason : reasonList) {
                reason.setIfChecked(reportDao.checkReason(report.getId(), reason.getReasonId()) > 0);
            }
//            List<ReportReason> reasonList = reportDao.getCommonReportReason(report.getId());
            ReportReason otherReason = reportDao.getOtherReportReason(report.getId());
            if(otherReason != null) {
                otherReason.setIfChecked(true);
                reasonList.add(otherReason);
            } else {
                reasonList.add(new ReportReason(0L, null, null, false));
            }
            String hUserName = report.gethUserId() == null ? null : reportDao.getUserName(report.gethUserId());
            String target = "";
            switch (report.getType()) {
                case 1:
                    target = reportDao.getPostName(report.getTarget());
                    break;
                case 2:
                    target = reportDao.getComment(report.getTarget());
                    break;
                case 3:
                    target = reportDao.getUserName(report.getTarget());
                    break;
            }
            ReportDto reportDto = new ReportDto(report.getId(),
                    report.getsUserId(), reportDao.getUserName(report.getsUserId()),
                    Constants.AVATAR_URL + reportDao.getUserAvatar(report.getsUserId()),
                    report.gethUserId(), hUserName,
                    report.getTarget(), target,
                    report.getType(), report.getTime(),
                    report.getState(), report.getPtime(),
                    report.getRemarks(), reasonList);
            reportDtoList.add(reportDto);
        }
        return reportDtoList;
    }

    @Override
    public void pass(ReportDto reportDto) {
        reportDao.handleReport(reportDto.getId(), 1, reportDto.getHUserId());
        switch (reportDto.getType()) {
            case 0:
                reportDao.banPost(reportDao.getPostVersionId(reportDto.getTargetID()));
                break;
            case 1:
                reportDao.banComment(reportDto.getTargetID());
                break;
            case 2:
                reportDao.banUser(reportDto.getTargetID());
                break;
        }
        applicationEventPublisher.publishEvent(new ReportPassEvent(this, reportDto.getId()));
    }

    @Override
    public void reject(Long id, CurrentUser user) {
        reportDao.handleReport(id, 2, user.getU_id());
        applicationEventPublisher.publishEvent(new ReportRejectEvent(this, id));
    }
}
